namespace sim {
  const MIN_MESSAGE_WAIT_MS = 200;

  export namespace U {
    export function perfNowUs(): number

    export function assert(cond: boolean, msg = "Assertion failed") {
      if (!cond) {
        debugger
        throw new Error(msg)
      }
    }
  }

  export class BaseBoard {

  }

  export let runtime: Runtime;

  export class Runtime {
    msybeUpdateDisplay() {
      throw new Error("Method not implemented.");
    }
    queueDisplayUpdate() {
      throw new Error("Method not implemented.");
    }
    dead: any;
    runFiberAsync(h: RefAction, ...arg1: any): void {
      throw new Error("Method not implemented.");
    }
    暂停断点: any;
    startTimeUs: number;
    start闲置() {
      throw new Error("Method not implemented.");
    }
    public 板: BaseBoard
    全局数 = 1000 // 数组
    errorHandler: (e: any) => void
    postError: (e: any) => void;
    stateChanged: () => void
  }

  enum LogType {
    UserSet, BackAdd, BackRemove
  }

  export type EventValueToActionArgs = (value: EventIDType) => any[]

  export type EventIDType = number | string

  export class EventQueue {

    max: number = 5;
    events: EventIDType[] = []

    private 等待者: ((v?: any) => void)[] = []
    private 锁: boolean = false

    private _处理程序: RefAction[] = [];
    private _addRemoveLog: { act: RefAction, log: LogType }[] = [];

    constructor(public runtime: Runtime, private valueToArgs?: EventValueToActionArgs) { }


    public push(e: EventIDType, notifyOne: boolean): Promise<void> {
      if (this.等待者.length > 0) {
        if (notifyOne) {
          const aw = this.等待者.shift()
          if (aw) aw()
        } else {
          const aws = this.等待者.slice()
          this.等待者 = []
          aws.forEach(aw => aw())
        }
      }

      if (this._处理程序.length == 0 || this.events.length > this.max)
        return Promise.resolve()
      this.events.push(e)
      if (!this.锁)
        return this.poke()
      else
        return Promise.resolve()


    }

    private poke(): Promise<void> {
      this.锁 = true
      let events = this.events
      // 所有事件都将由下面的并发promisified代码处理，因此重新开始

      this.events = []
      return Promise.all(events).then((value) => {
        value.forEach(v => {
          return Promise.all(this._处理程序).then(handler => {
            handler.forEach(h => {
              return this.runtime.runFiberAsync(h, ...(this.valueToArgs ? this.valueToArgs(v) : [v]))
            })
          })
        })

      }).then(() => {
        if (this.events.length > 0) {
          return this.poke()
        } else {
          this.锁 = false
          this._addRemoveLog.forEach(l => {
            if (l.log === LogType.BackAdd) {
              this.addHandler(l.act)
            } else if (l.log === LogType.BackRemove) {
              this.removeHandler(l.act)
            } else {
              this.setHandler(l.act)
            }
          })
          this._addRemoveLog = []
          return Promise.resolve()
        }
      })

    }

    get handlears() {
      return this._处理程序
    }



    addAwaiter(awaiter: (value?: any) => void) {
      this.等待者.push(awaiter);
    }
    setHandler(handler: RefAction) {
      if (!this.锁) {
        this._处理程序 = [handler]
      } else {
        this._addRemoveLog.push({ act: handler, log: LogType.UserSet })
      }
    }


    removeHandler(handler: RefAction) {
      if (!this.锁) {
        let index = this._处理程序.indexOf(handler)
        if (index != -1)
          this._处理程序.splice(index, 1)
      } else {
        this._addRemoveLog.push({ act: handler, log: LogType.BackRemove })
      }
    }
    addHandler(handler: RefAction) {
      if (!this.锁) {
        let index = this._处理程序.indexOf(handler)
        if (index == -1) {
          this._处理程序.push(a)
        }
      } else {
        this._addRemoveLog.push({ act: arguments, log: LogType.BackAdd })
      }
    }
  }

  export class PerfCounter {
    start = 0
    numstops = 0
    value = 0
    lastFew = new Uint32Array(32)
    lastFewPtr = 0
    constructor(public name: string) { }
  }

}